home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 24 / Amiga Format AFCD24 (Feb 1998, Issue 108).iso / -in_the_mag- / emulation / amiga / uae-0.7.0b2 / src / cia.c < prev    next >
C/C++ Source or Header  |  1998-01-20  |  19KB  |  810 lines

  1.  /*
  2.   * UAE - The Un*x Amiga Emulator
  3.   *
  4.   * CIA chip support
  5.   *
  6.   * Copyright 1995 Bernd Schmidt, Alessandro Bissacco
  7.   * Copyright 1996, 1997 Stefan Reinauer, Christian Schmitt
  8.   */
  9.  
  10. #include "sysconfig.h"
  11. #include "sysdeps.h"
  12. #include <assert.h>
  13.  
  14. #include "config.h"
  15. #include "options.h"
  16. #include "threaddep/penguin.h"
  17. #include "gensound.h"
  18. #include "sounddep/sound.h"
  19. #include "events.h"
  20. #include "memory.h"
  21. #include "custom.h"
  22. #include "cia.h"
  23. #include "serial.h"
  24. #include "disk.h"
  25. #include "xwin.h"
  26. #include "keybuf.h"
  27. #include "gui.h"
  28.  
  29. #define DIV10 5 /* Yes, a bad identifier. */
  30.  
  31. /* battclock stuff */
  32. #define RTC_D_ADJ      8
  33. #define RTC_D_IRQ      4
  34. #define RTC_D_BUSY     2
  35. #define RTC_D_HOLD     1
  36. #define RTC_E_t1       8
  37. #define RTC_E_t0       4
  38. #define RTC_E_INTR     2
  39. #define RTC_E_MASK     1
  40. #define RTC_F_TEST     8
  41. #define RTC_F_24_12    4
  42. #define RTC_F_STOP     2
  43. #define RTC_F_RSET     1
  44.  
  45. static unsigned int clock_control_d = RTC_D_ADJ + RTC_D_HOLD;
  46. static unsigned int clock_control_e = 0;
  47. static unsigned int clock_control_f = RTC_F_24_12;
  48.  
  49. unsigned int ciaaicr,ciaaimask,ciabicr,ciabimask;
  50. unsigned int ciaacra,ciaacrb,ciabcra,ciabcrb;
  51. unsigned long ciaata,ciaatb,ciabta,ciabtb;
  52. unsigned long ciaatod,ciabtod,ciaatol,ciabtol,ciaaalarm,ciabalarm;
  53. int ciaatlatch,ciabtlatch;
  54.  
  55. unsigned int ciabpra;
  56.  
  57. unsigned int gui_ledstate;
  58.  
  59. static unsigned long ciaala,ciaalb,ciabla,ciablb;
  60. static int ciaatodon, ciabtodon;
  61. static unsigned int ciaapra,ciaaprb,ciaadra,ciaadrb,ciaasdr;
  62. static unsigned int ciabprb,ciabdra,ciabdrb,ciabsdr;
  63. static int div10;
  64. static int kbstate, kback, ciaasdr_unread = 0;
  65.  
  66. static int prtopen;
  67. static FILE *prttmp;
  68.  
  69. static void setclr(unsigned int *p, unsigned int val)
  70. {
  71.     if (val & 0x80) {
  72.     *p |= val & 0x7F;
  73.     } else {
  74.     *p &= ~val;
  75.     }
  76. }
  77.  
  78. static void RethinkICRA(void)
  79. {
  80.     if (ciaaimask & ciaaicr) {
  81.     ciaaicr |= 0x80;
  82.     custom_bank.wput(0xDFF09C,0x8008);
  83.     } else {
  84.     ciaaicr &= 0x7F;
  85. /*    custom_bank.wput(0xDFF09C,0x0008);*/
  86.     }
  87. }
  88.  
  89. static void RethinkICRB(void)
  90. {
  91. #if 0 /* ??? What's this then? */
  92.     if (ciabicr & 0x10) {
  93.     custom_bank.wput(0xDFF09C,0x9000);
  94.     }
  95. #endif
  96.     if (ciabimask & ciabicr) {
  97.     ciabicr |= 0x80;
  98.     custom_bank.wput(0xDFF09C,0xA000);
  99.     } else {
  100.     ciabicr &= 0x7F;
  101. /*    custom_bank.wput(0xDFF09C,0x2000);*/
  102.     }
  103. }
  104.  
  105. static int lastdiv10;
  106.  
  107. static void CIA_update(void)
  108. {
  109.     unsigned long int ccount = cycles - eventtab[ev_cia].oldcycles + lastdiv10;
  110.     unsigned long int ciaclocks = ccount / DIV10;
  111.  
  112.     int aovfla = 0, aovflb = 0, bovfla = 0, bovflb = 0;
  113.  
  114.     lastdiv10 = div10;
  115.     div10 = ccount % DIV10;
  116.  
  117.     /* CIA A timers */
  118.     if ((ciaacra & 0x21) == 0x01) {
  119.     assert((ciaata+1) >= ciaclocks);
  120.     if ((ciaata+1) == ciaclocks) {
  121.         aovfla = 1;
  122.         if ((ciaacrb & 0x61) == 0x41) {
  123.         if (ciaatb-- == 0) aovflb = 1;
  124.         }
  125.     }
  126.     ciaata -= ciaclocks;
  127.     }
  128.     if ((ciaacrb & 0x61) == 0x01) {
  129.     assert((ciaatb+1) >= ciaclocks);
  130.     if ((ciaatb+1) == ciaclocks) aovflb = 1;
  131.     ciaatb -= ciaclocks;
  132.     }
  133.  
  134.     /* CIA B timers */
  135.     if ((ciabcra & 0x21) == 0x01) {
  136.     assert((ciabta+1) >= ciaclocks);
  137.     if ((ciabta+1) == ciaclocks) {
  138.         bovfla = 1;
  139.         if ((ciabcrb & 0x61) == 0x41) {
  140.         if (ciabtb-- == 0) bovflb = 1;
  141.         }
  142.     }
  143.     ciabta -= ciaclocks;
  144.     }
  145.     if ((ciabcrb & 0x61) == 0x01) {
  146.     assert ((ciabtb+1) >= ciaclocks);
  147.     if ((ciabtb+1) == ciaclocks) bovflb = 1;
  148.     ciabtb -= ciaclocks;
  149.     }
  150.     if (aovfla) {
  151.     ciaaicr |= 1; RethinkICRA();
  152.     ciaata = ciaala;
  153.     if (ciaacra & 0x8) ciaacra &= ~1;
  154.     }
  155.     if (aovflb) {
  156.     ciaaicr |= 2; RethinkICRA();
  157.     ciaatb = ciaalb;
  158.     if (ciaacrb & 0x8) ciaacrb &= ~1;
  159.     }
  160.     if (bovfla) {
  161.     ciabicr |= 1; RethinkICRB();
  162.     ciabta = ciabla;
  163.     if (ciabcra & 0x8) ciabcra &= ~1;
  164.     }
  165.     if (bovflb) {
  166.     ciabicr |= 2; RethinkICRB();
  167.     ciabtb = ciablb;
  168.     if (ciabcrb & 0x8) ciabcrb &= ~1;
  169.     }
  170. }
  171.  
  172. static void CIA_calctimers(void)
  173. {
  174.     int ciaatimea = -1, ciaatimeb = -1, ciabtimea = -1, ciabtimeb = -1;
  175.  
  176.     eventtab[ev_cia].oldcycles = cycles;
  177.  
  178.     if ((ciaacra & 0x21) == 0x01) {
  179.     ciaatimea = (DIV10-div10) + DIV10*ciaata;
  180.     }
  181.     if ((ciaacrb & 0x61) == 0x41) {
  182.     /* Timer B will not get any pulses if Timer A is off. */
  183.     if (ciaatimea >= 0) {
  184.         /* If Timer A is in one-shot mode, and Timer B needs more than
  185.          * one pulse, it will not underflow. */
  186.         if (ciaatb == 0 || (ciaacra & 0x8) == 0) {
  187.         /* Otherwise, we can determine the time of the underflow. */
  188.         ciaatimeb = ciaatimea + ciaala * DIV10 * ciaatb;
  189.         }
  190.     }
  191.     }
  192.     if ((ciaacrb & 0x61) == 0x01) {
  193.     ciaatimeb = (DIV10-div10) + DIV10*ciaatb;
  194.     }
  195.  
  196.     if ((ciabcra & 0x21) == 0x01) {
  197.     ciabtimea = (DIV10-div10) + DIV10*ciabta;
  198.     }
  199.     if ((ciabcrb & 0x61) == 0x41) {
  200.     /* Timer B will not get any pulses if Timer A is off. */
  201.     if (ciabtimea >= 0) {
  202.         /* If Timer A is in one-shot mode, and Timer B needs more than
  203.          * one pulse, it will not underflow. */
  204.         if (ciabtb == 0 || (ciabcra & 0x8) == 0) {
  205.         /* Otherwise, we can determine the time of the underflow. */
  206.         ciabtimeb = ciabtimea + ciabla * DIV10 * ciabtb;
  207.         }
  208.     }
  209.     }
  210.     if ((ciabcrb & 0x61) == 0x01) {
  211.     ciabtimeb = (DIV10-div10) + DIV10*ciabtb;
  212.     }
  213.     eventtab[ev_cia].active = (ciaatimea != -1 || ciaatimeb != -1
  214.                    || ciabtimea != -1 || ciabtimeb != -1);
  215.     if (eventtab[ev_cia].active) {
  216.     unsigned long int ciatime = ~0L;
  217.     if (ciaatimea != -1) ciatime = ciaatimea;
  218.     if (ciaatimeb != -1 && ciaatimeb < ciatime) ciatime = ciaatimeb;
  219.     if (ciabtimea != -1 && ciabtimea < ciatime) ciatime = ciabtimea;
  220.     if (ciabtimeb != -1 && ciabtimeb < ciatime) ciatime = ciabtimeb;
  221.     eventtab[ev_cia].evtime = ciatime + cycles;
  222.     }
  223.     events_schedule();
  224. }
  225.  
  226. void CIA_handler(void)
  227. {
  228.     CIA_update();
  229.     CIA_calctimers();
  230. }
  231.  
  232. void diskindex_handler(void)
  233. {
  234.     eventtab[ev_diskindex].evtime += cycles - eventtab[ev_diskindex].oldcycles;
  235.     eventtab[ev_diskindex].oldcycles = cycles;
  236. /*    printf(".\n");*/
  237.     ciabicr |= 0x10;
  238.     RethinkICRB();
  239. }
  240.  
  241. void CIA_hsync_handler(void)
  242. {
  243.     static unsigned int keytime = 0, sleepyhead = 0;
  244.  
  245.     if (ciabtodon)
  246.     ciabtod++;
  247.     ciabtod &= 0xFFFFFF;
  248.  
  249.     if (ciabtod == ciabalarm) {
  250.     ciabicr |= 4; RethinkICRB();
  251.     }
  252.  
  253.     if (doreadser) doreadser = SERDATS();
  254.         /*  check wether the serial port gets some data  */
  255.  
  256.     if (keys_available() && kback && (++keytime & 15) == 0) {
  257.     /*
  258.      * This hack lets one possible ciaaicr cycle go by without any key
  259.      * being read, for every cycle in which a key is pulled out of the
  260.      * queue.  If no hack is used, a lot of key events just get lost
  261.      * when you type fast.  With a simple hack that waits for ciaasdr
  262.      * to be read before feeding it another, it will keep up until the
  263.      * queue gets about 14 characters ahead and then lose events, and
  264.      * the mouse pointer will freeze while typing is being taken in.
  265.      * With this hack, you can type 30 or 40 characters ahead with little
  266.      * or no lossage, and the mouse doesn't get stuck.  The tradeoff is
  267.      * that the total slowness of typing appearing on screen is worse.
  268.      */
  269.     if (ciaasdr_unread == 2)
  270.         ciaasdr_unread = 0;
  271.     else if (ciaasdr_unread == 0) {
  272.         switch (kbstate) {
  273.          case 0:
  274.         ciaasdr = (uae_s8)~0xFB; /* aaarghh... stupid compiler */
  275.         kbstate++;
  276.         break;
  277.          case 1:
  278.         kbstate++;
  279.         ciaasdr = (uae_s8)~0xFD;
  280.         break;
  281.          case 2:
  282.         ciaasdr = ~get_next_key();
  283.         ciaasdr_unread = 1;      /* interlock to prevent lost keystrokes */
  284.         break;
  285.         }
  286.         ciaaicr |= 8;
  287.         RethinkICRA();
  288.         sleepyhead = 0;
  289.     } else if (!(++sleepyhead & 15))
  290.         ciaasdr_unread = 0;          /* give up on this key event after unread for a long time */
  291.     }
  292. }
  293.  
  294. void CIA_vsync_handler()
  295. {
  296.     if (ciaatodon)
  297.     ciaatod++;
  298.     ciaatod &= 0xFFFFFF;
  299.     if (ciaatod == ciaaalarm) {
  300.     ciaaicr |= 4; RethinkICRA();
  301.     }
  302.  
  303.     doreadser = 1;
  304.     serstat = -1;
  305.     serial_flush_buffer();
  306. }
  307.  
  308. static uae_u8 ReadCIAA(unsigned int addr)
  309. {
  310.     unsigned int tmp;
  311.  
  312.     switch(addr & 0xf){
  313.      case 0:
  314.     if (currprefs.use_serial && (serstat < 0)) /* Only read status when needed */
  315.     serstat=serial_readstatus();        /* and only once per frame */
  316.  
  317.     tmp = (DISK_status() & 0x3C);
  318.     if ((JSEM_ISMOUSE (0, currprefs.fake_joystick) && !buttonstate[0])
  319.         || (!JSEM_ISMOUSE (0, currprefs.fake_joystick) && !(joy0button & 1)))
  320.         tmp |= 0x40;
  321.     if (!(joy1button & 1))
  322.         tmp |= 0x80;
  323.     return tmp;
  324.      case 1:
  325.     return ciaaprb;
  326.      case 2:
  327.     return ciaadra;
  328.      case 3:
  329.     return ciaadrb;
  330.      case 4:
  331.     return ciaata & 0xff;
  332.      case 5:
  333.     return ciaata >> 8;
  334.      case 6:
  335.     return ciaatb & 0xff;
  336.      case 7:
  337.     return ciaatb >> 8;
  338.      case 8:
  339.     if (ciaatlatch) {
  340.         ciaatlatch = 0;
  341.         return ciaatol & 0xff;
  342.     } else
  343.         return ciaatod & 0xff;
  344.      case 9:
  345.     if (ciaatlatch)
  346.         return (ciaatol >> 8) & 0xff;
  347.     else
  348.         return (ciaatod >> 8) & 0xff;
  349.      case 10:
  350.     ciaatlatch = 1;
  351.     ciaatol = ciaatod; /* ??? only if not already latched? */
  352.     return (ciaatol >> 16) & 0xff;
  353.      case 12:
  354.     if (ciaasdr == 1) ciaasdr_unread = 2;
  355.     return ciaasdr;
  356.      case 13:
  357.     tmp = ciaaicr; ciaaicr = 0; RethinkICRA(); return tmp;
  358.      case 14:
  359.     return ciaacra;
  360.      case 15:
  361.     return ciaacrb;
  362.     }
  363.     return 0;
  364. }
  365.  
  366. static uae_u8 ReadCIAB(unsigned int addr)
  367. {
  368.     unsigned int tmp;
  369.  
  370.     switch(addr & 0xf){
  371.      case 0:
  372.     if (currprefs.use_serial && serstat < 0) /* Only read status when needed */
  373.       serstat=serial_readstatus();           /* and only once per frame      */
  374.     return ciabpra;
  375.      case 1:
  376.     return ciabprb;
  377.      case 2:
  378.     return ciabdra;
  379.      case 3:
  380.     return ciabdrb;
  381.      case 4:
  382.     return ciabta & 0xff;
  383.      case 5:
  384.     return ciabta >> 8;
  385.      case 6:
  386.     return ciabtb & 0xff;
  387.      case 7:
  388.     return ciabtb >> 8;
  389.      case 8:
  390.     if (ciabtlatch) {
  391.         ciabtlatch = 0;
  392.         return ciabtol & 0xff;
  393.     } else
  394.         return ciabtod & 0xff;
  395.      case 9:
  396.     if (ciabtlatch)
  397.         return (ciabtol >> 8) & 0xff;
  398.     else
  399.         return (ciabtod >> 8) & 0xff;
  400.      case 10:
  401.     ciabtlatch = 1;
  402.     ciabtol = ciabtod;
  403.     return (ciabtol >> 16) & 0xff;
  404.      case 12:
  405.     return ciabsdr;
  406.      case 13:
  407.     tmp = ciabicr; ciabicr = 0; RethinkICRB();
  408.     return tmp;
  409.      case 14:
  410.     return ciabcra;
  411.      case 15:
  412.     return ciabcrb;
  413.     }
  414.     return 0;
  415. }
  416.  
  417. static void WriteCIAA(uae_u16 addr,uae_u8 val)
  418. {
  419.     int oldled, oldovl;
  420.     switch(addr & 0xf){
  421.      case 0:
  422.     oldovl = ciaapra & 1;
  423.     oldled = ciaapra & 2;
  424.     ciaapra = (ciaapra & ~0x3) | (val & 0x3); LED(ciaapra & 0x2);
  425.     gui_ledstate = (gui_ledstate & ~1) | ((ciaapra & 2) >> 1);
  426.     if ((ciaapra & 2) != oldled)
  427.         gui_led (0, !(ciaapra & 2));
  428.     if ((ciaapra & 1) != oldovl) {
  429.         map_banks(oldovl || ersatzkickfile ? &chipmem_bank : &kickmem_bank, 0, 32);
  430.     }
  431.     break;
  432.      case 1:
  433.     ciaaprb = val;
  434.     if (prtopen==1) {
  435. #ifndef __DOS__
  436.         fprintf (prttmp,"%c",val);
  437. #else
  438.         fputc (val, prttmp);
  439.         fflush (prttmp);
  440. #endif
  441.         if (val==0x04) {
  442. #if defined(__unix) && !defined(__BEOS__) && !defined(__DOS__)
  443.         pclose (prttmp);
  444. #else
  445.         fclose (prttmp);
  446. #endif
  447.         prtopen = 0;
  448.         }
  449.     } else {
  450. #if defined(__unix) && !defined(__BEOS__) && !defined(__DOS__)
  451.         prttmp=(FILE *)popen ((char *)prtname,"w");
  452. #else
  453.         prttmp=(FILE *)fopen ((char *)prtname,"wb");
  454. #endif
  455.         if (prttmp != NULL) {
  456.         prtopen = 1;
  457. #ifndef __DOS__
  458.         fprintf (prttmp,"%c",val);
  459. #else
  460.         fputc (val, prttmp);
  461.         fflush (prttmp);
  462. #endif
  463.         }
  464.     }
  465.     ciaaicr |= 0x10;
  466.     break;
  467.      case 2:
  468.     ciaadra = val; break;
  469.      case 3:
  470.     ciaadrb = val; break;
  471.      case 4:
  472.     CIA_update();
  473.     ciaala = (ciaala & 0xff00) | val;
  474.     CIA_calctimers();
  475.     break;
  476.      case 5:
  477.     CIA_update();
  478.     ciaala = (ciaala & 0xff) | (val << 8);
  479.     if ((ciaacra & 1) == 0)
  480.         ciaata = ciaala;
  481.     if (ciaacra & 8) {
  482.         ciaata = ciaala;
  483.         ciaacra |= 1;
  484.     }
  485.     CIA_calctimers();
  486.     break;
  487.      case 6:
  488.     CIA_update();
  489.     ciaalb = (ciaalb & 0xff00) | val;
  490.     CIA_calctimers();
  491.     break;
  492.      case 7:
  493.     CIA_update();
  494.     ciaalb = (ciaalb & 0xff) | (val << 8);
  495.     if ((ciaacrb & 1) == 0)
  496.         ciaatb = ciaalb;
  497.     if (ciaacrb & 8) {
  498.         ciaatb = ciaalb;
  499.         ciaacrb |= 1;
  500.     }
  501.     CIA_calctimers();
  502.     break;
  503.      case 8:
  504.     if (ciaacrb & 0x80){
  505.         ciaaalarm = (ciaaalarm & ~0xff) | val;
  506.     } else {
  507.         ciaatod = (ciaatod & ~0xff) | val;
  508.         ciaatodon = 1;
  509.     }
  510.     break;
  511.      case 9:
  512.     if (ciaacrb & 0x80){
  513.         ciaaalarm = (ciaaalarm & ~0xff00) | (val << 8);
  514.     } else {
  515.         ciaatod = (ciaatod & ~0xff00) | (val << 8);
  516.         ciaatodon = 0;
  517.     }
  518.     break;
  519.      case 10:
  520.     if (ciaacrb & 0x80){
  521.         ciaaalarm = (ciaaalarm & ~0xff0000) | (val << 16);
  522.     } else {
  523.         ciaatod = (ciaatod & ~0xff0000) | (val << 16);
  524.         ciaatodon = 0;
  525.     }
  526.     break;
  527.      case 12:
  528.     ciaasdr = val; break;
  529.      case 13:
  530.     setclr(&ciaaimask,val); break; /* ??? call RethinkICR() ? */
  531.      case 14:
  532.     CIA_update();
  533.     ciaacra = val;
  534.     if (ciaacra & 0x10){
  535.         ciaacra &= ~0x10;
  536.         ciaata = ciaala;
  537.     }
  538.     if (ciaacra & 0x40) {
  539.         kback = 1;
  540.     }
  541.     CIA_calctimers();
  542.     break;
  543.      case 15:
  544.     CIA_update();
  545.     ciaacrb = val;
  546.     if (ciaacrb & 0x10){
  547.         ciaacrb &= ~0x10;
  548.         ciaatb = ciaalb;
  549.     }
  550.     CIA_calctimers();
  551.     break;
  552.     }
  553. }
  554.  
  555. static void WriteCIAB(uae_u16 addr,uae_u8 val)
  556. {
  557.     int oldval;
  558.     switch(addr & 0xf){
  559.      case 0:
  560.     if (currprefs.use_serial) {
  561.       oldval = ciabpra;
  562.       ciabpra  = serial_writestatus(oldval,val);
  563.     } else
  564.       ciabpra  = val;
  565.     break;
  566.      case 1:
  567.     ciabprb = val; DISK_select(val); break;
  568.      case 2:
  569.     ciabdra = val; break;
  570.      case 3:
  571.     ciabdrb = val; break;
  572.      case 4:
  573.     CIA_update();
  574.     ciabla = (ciabla & 0xff00) | val;
  575.     CIA_calctimers();
  576.     break;
  577.      case 5:
  578.     CIA_update();
  579.     ciabla = (ciabla & 0xff) | (val << 8);
  580.     if ((ciabcra & 1) == 0)
  581.         ciabta = ciabla;
  582.     if (ciabcra & 8) {
  583.         ciabta = ciabla;
  584.         ciabcra |= 1;
  585.     }
  586.     CIA_calctimers();
  587.     break;
  588.      case 6:
  589.     CIA_update();
  590.     ciablb = (ciablb & 0xff00) | val;
  591.     CIA_calctimers();
  592.     break;
  593.      case 7:
  594.     CIA_update();
  595.     ciablb = (ciablb & 0xff) | (val << 8);
  596.     if ((ciabcrb & 1) == 0)
  597.         ciabtb = ciablb;
  598.     if (ciabcrb & 8) {
  599.         ciabtb = ciablb;
  600.         ciabcrb |= 1;
  601.     }
  602.     CIA_calctimers();
  603.     break;
  604.      case 8:
  605.     if (ciabcrb & 0x80){
  606.         ciabalarm = (ciabalarm & ~0xff) | val;
  607.     } else {
  608.         ciabtod = (ciabtod & ~0xff) | val;
  609.         ciabtodon = 1;
  610.     }
  611.     break;
  612.      case 9:
  613.     if (ciabcrb & 0x80){
  614.         ciabalarm = (ciabalarm & ~0xff00) | (val << 8);
  615.     } else {
  616.         ciabtod = (ciabtod & ~0xff00) | (val << 8);
  617.         ciabtodon = 0;
  618.     }
  619.     break;
  620.      case 10:
  621.     if (ciabcrb & 0x80){
  622.         ciabalarm = (ciabalarm & ~0xff0000) | (val << 16);
  623.     } else {
  624.         ciabtod = (ciabtod & ~0xff0000) | (val << 16);
  625.         ciabtodon = 0;
  626.     }
  627.     break;
  628.      case 12:
  629.     ciabsdr = val;
  630.     break;
  631.      case 13:
  632.     setclr(&ciabimask,val);
  633.     break;
  634.      case 14:
  635.     CIA_update();
  636.     ciabcra = val;
  637.     if (ciabcra & 0x10){
  638.         ciabcra &= ~0x10;
  639.         ciabta = ciabla;
  640.     }
  641.     CIA_calctimers();
  642.     break;
  643.      case 15:
  644.     CIA_update();
  645.     ciabcrb = val;
  646.     if (ciabcrb & 0x10){
  647.         ciabcrb &= ~0x10;
  648.         ciabtb = ciablb;
  649.     }
  650.     CIA_calctimers();
  651.     break;
  652.     }
  653. }
  654.  
  655. void CIA_reset(void)
  656. {
  657.     kback = 1;
  658.     kbstate = 0;
  659.  
  660.     ciaatlatch = ciabtlatch = 0;
  661.     ciaapra = 3;
  662.     ciaatod = ciabtod = 0; ciaatodon = ciabtodon = 0;
  663.     ciaaicr = ciabicr = ciaaimask = ciabimask = 0;
  664.     ciaacra = ciaacrb = ciabcra = ciabcrb = 0x4; /* outmode = toggle; */
  665.     ciaala = ciaalb = ciabla = ciablb = ciaata = ciaatb = ciabta = ciabtb = 0xFFFF;
  666.     div10 = 0;
  667.     lastdiv10 = 0;
  668.     CIA_calctimers();
  669.     ciabpra = 0x8C;
  670.     if (! ersatzkickfile)
  671.     map_banks(&kickmem_bank, 0, 32);
  672.  
  673.     if (currprefs.use_serial) serial_dtr_off(); /* Drop DTR at reset */
  674. }
  675.  
  676. void dumpcia(void)
  677. {
  678.     printf("A: CRA: %02x, CRB: %02x, IMASK: %02x, TOD: %08lx %7s TA: %04lx, TB: %04lx\n",
  679.        (int)ciaacra, (int)ciaacrb, (int)ciaaimask, ciaatod,
  680.        ciaatlatch ? " latched" : "", ciaata, ciaatb);
  681.     printf("B: CRA: %02x, CRB: %02x, IMASK: %02x, TOD: %08lx %7s TA: %04lx, TB: %04lx\n",
  682.        (int)ciabcra, (int)ciabcrb, (int)ciabimask, ciabtod,
  683.        ciabtlatch ? " latched" : "", ciabta, ciabtb);
  684. }
  685.  
  686. /* CIA memory access */
  687.  
  688. static uae_u32 cia_lget(uaecptr) REGPARAM;
  689. static uae_u32 cia_wget(uaecptr) REGPARAM;
  690. static uae_u32 cia_bget(uaecptr) REGPARAM;
  691. static void  cia_lput(uaecptr, uae_u32) REGPARAM;
  692. static void  cia_wput(uaecptr, uae_u32) REGPARAM;
  693. static void  cia_bput(uaecptr, uae_u32) REGPARAM;
  694.  
  695. addrbank cia_bank = {
  696.     cia_lget, cia_wget, cia_bget,
  697.     cia_lput, cia_wput, cia_bput,
  698.     default_xlate, default_check
  699. };
  700.  
  701. uae_u32 REGPARAM2 cia_lget(uaecptr addr)
  702. {
  703.     return cia_bget(addr+3);
  704. }
  705.  
  706. uae_u32 REGPARAM2 cia_wget(uaecptr addr)
  707. {
  708.     return cia_bget(addr+1);
  709. }
  710.  
  711. uae_u32 REGPARAM2 cia_bget(uaecptr addr)
  712. {
  713.     if ((addr & 0x3001) == 0x2001)
  714.     return ReadCIAA((addr & 0xF00) >> 8);
  715.     if ((addr & 0x3001) == 0x1000)
  716.     return ReadCIAB((addr & 0xF00) >> 8);
  717.     return 0;
  718. }
  719.  
  720. void REGPARAM2 cia_lput(uaecptr addr, uae_u32 value)
  721. {
  722.     cia_bput(addr+3,value); /* FIXME ? */
  723. }
  724.  
  725. void REGPARAM2 cia_wput(uaecptr addr, uae_u32 value)
  726. {
  727.     cia_bput(addr+1,value);
  728. }
  729.  
  730. void REGPARAM2 cia_bput(uaecptr addr, uae_u32 value)
  731. {
  732.     if ((addr & 0x3001) == 0x2001)
  733.     WriteCIAA((addr & 0xF00) >> 8,value);
  734.     if ((addr & 0x3001) == 0x1000)
  735.     WriteCIAB((addr & 0xF00) >> 8,value);
  736. }
  737.  
  738. /* battclock memory access */
  739.  
  740. static uae_u32 clock_lget(uaecptr) REGPARAM;
  741. static uae_u32 clock_wget(uaecptr) REGPARAM;
  742. static uae_u32 clock_bget(uaecptr) REGPARAM;
  743. static void  clock_lput(uaecptr, uae_u32) REGPARAM;
  744. static void  clock_wput(uaecptr, uae_u32) REGPARAM;
  745. static void  clock_bput(uaecptr, uae_u32) REGPARAM;
  746.  
  747. addrbank clock_bank = {
  748.     clock_lget, clock_wget, clock_bget,
  749.     clock_lput, clock_wput, clock_bput,
  750.     default_xlate, default_check
  751. };
  752.  
  753. uae_u32 REGPARAM2 clock_lget(uaecptr addr)
  754. {
  755.     return clock_bget(addr+3);
  756. }
  757.  
  758. uae_u32 REGPARAM2 clock_wget(uaecptr addr)
  759. {
  760.     return clock_bget(addr+1);
  761. }
  762.  
  763. uae_u32 REGPARAM2 clock_bget(uaecptr addr)
  764. {
  765.     time_t t=time(0);
  766.     struct tm *ct;
  767.     ct=localtime(&t);
  768.     switch (addr & 0x3f)
  769.     {
  770.      case 0x03: return ct->tm_sec % 10;
  771.      case 0x07: return ct->tm_sec / 10;
  772.      case 0x0b: return ct->tm_min % 10;
  773.      case 0x0f: return ct->tm_min / 10;
  774.      case 0x13: return ct->tm_hour % 10;
  775.      case 0x17: return ct->tm_hour / 10;
  776.      case 0x1b: return ct->tm_mday % 10;
  777.      case 0x1f: return ct->tm_mday / 10;
  778.      case 0x23: return (ct->tm_mon+1) % 10;
  779.      case 0x27: return (ct->tm_mon+1) / 10;
  780.      case 0x2b: return ct->tm_year % 10;
  781.      case 0x2f: return ct->tm_year / 10;
  782.  
  783.      case 0x33: return ct->tm_wday;  /*Hack by -=SR=- */
  784.      case 0x37: return clock_control_d;
  785.      case 0x3b: return clock_control_e;
  786.      case 0x3f: return clock_control_f;
  787.     }
  788.     return 0;
  789. }
  790.  
  791. void REGPARAM2 clock_lput(uaecptr addr, uae_u32 value)
  792. {
  793.     /* No way */
  794. }
  795.  
  796. void REGPARAM2 clock_wput(uaecptr addr, uae_u32 value)
  797. {
  798.     /* No way */
  799. }
  800.  
  801. void REGPARAM2 clock_bput(uaecptr addr, uae_u32 value)
  802. {
  803.     switch (addr & 0x3f)
  804.     {
  805.      case 0x37: clock_control_d=value; break;
  806.      case 0x3b: clock_control_e=value; break;
  807.      case 0x3f: clock_control_f=value; break;
  808.     }
  809. }
  810.